/**
 * 统一错误处理系统
 */

import { ElMessage } from 'element-plus'
import { log } from './logger'
import type { AxiosError } from 'axios'

// 错误类型枚举
export enum ErrorType {
  NETWORK = 'NETWORK',
  VALIDATION = 'VALIDATION',
  AUTHENTICATION = 'AUTHENTICATION',
  AUTHORIZATION = 'AUTHORIZATION',
  NOT_FOUND = 'NOT_FOUND',
  SERVER = 'SERVER',
  BUSINESS = 'BUSINESS',
  UNKNOWN = 'UNKNOWN'
}

// 错误详情接口
export interface ErrorDetail {
  msg: string
  param?: string
  location?: string
  path?: string
}

// 应用错误类
export class AppError extends Error {
  public readonly type: ErrorType
  public readonly code?: string | number
  public readonly details?: ErrorDetail[]
  public readonly originalError?: any

  constructor(
    message: string,
    type: ErrorType = ErrorType.UNKNOWN,
    code?: string | number,
    details?: ErrorDetail[],
    originalError?: any
  ) {
    super(message)
    this.name = 'AppError'
    this.type = type
    this.code = code
    this.details = details
    this.originalError = originalError
  }
}

// 错误处理器类
class ErrorHandler {
  // 处理API错误
  handleApiError(error: AxiosError, source?: string): AppError {
    const response = error.response
    const request = error.request
    
    log.error('API错误', {
      url: error.config?.url,
      method: error.config?.method,
      status: response?.status,
      data: response?.data,
      message: error.message
    }, source)

    if (response) {
      // 服务器响应错误
      const { status, data } = response
      
      switch (status) {
        case 400:
          return new AppError(
            (data as any)?.message || '请求参数错误',
            ErrorType.VALIDATION,
            status,
            (data as any)?.details,
            error
          )
        
        case 401:
          return new AppError(
            '登录已过期，请重新登录',
            ErrorType.AUTHENTICATION,
            status,
            undefined,
            error
          )
        
        case 403:
          return new AppError(
            '没有权限执行此操作',
            ErrorType.AUTHORIZATION,
            status,
            undefined,
            error
          )
        
        case 404:
          return new AppError(
            '请求的资源不存在',
            ErrorType.NOT_FOUND,
            status,
            undefined,
            error
          )
        
        case 409:
          return new AppError(
            (data as any)?.message || '数据冲突',
            ErrorType.BUSINESS,
            status,
            (data as any)?.details,
            error
          )
        
        case 429:
          return new AppError(
            '请求过于频繁，请稍后再试',
            ErrorType.BUSINESS,
            status,
            undefined,
            error
          )
        
        case 500:
        case 502:
        case 503:
        case 504:
          return new AppError(
            '服务器错误，请稍后重试',
            ErrorType.SERVER,
            status,
            undefined,
            error
          )
        
        default:
          return new AppError(
            (data as any)?.message || '请求失败',
            ErrorType.UNKNOWN,
            status,
            (data as any)?.details,
            error
          )
      }
    } else if (request) {
      // 网络错误
      return new AppError(
        '网络连接失败，请检查网络设置',
        ErrorType.NETWORK,
        undefined,
        undefined,
        error
      )
    } else {
      // 其他错误
      return new AppError(
        error.message || '未知错误',
        ErrorType.UNKNOWN,
        undefined,
        undefined,
        error
      )
    }
  }

  // 处理业务错误
  handleBusinessError(message: string, details?: ErrorDetail[], source?: string): AppError {
    log.warn('业务错误', { message, details }, source)
    return new AppError(message, ErrorType.BUSINESS, undefined, details)
  }

  // 处理验证错误
  handleValidationError(message: string, details?: ErrorDetail[], source?: string): AppError {
    log.warn('验证错误', { message, details }, source)
    return new AppError(message, ErrorType.VALIDATION, undefined, details)
  }

  // 显示错误消息
  showError(error: AppError | Error | string, showDetails = false) {
    let message: string
    let details: ErrorDetail[] | undefined

    if (typeof error === 'string') {
      message = error
    } else if (error instanceof AppError) {
      message = error.message
      details = error.details
      
      // 记录错误日志
      log.error('应用错误', {
        type: error.type,
        code: error.code,
        message: error.message,
        details: error.details
      })
    } else {
      message = error.message || '未知错误'
      log.error('未处理错误', error)
    }

    // 显示主要错误消息
    ElMessage.error(message)

    // 如果需要显示详细信息且存在详细信息
    if (showDetails && details && details.length > 0) {
      const detailMessages = details.map(detail => detail.msg).join('\n')
      setTimeout(() => {
        ElMessage.warning(detailMessages)
      }, 500)
    }
  }

  // 显示成功消息
  showSuccess(message: string) {
    ElMessage.success(message)
  }

  // 显示警告消息
  showWarning(message: string) {
    ElMessage.warning(message)
  }

  // 显示信息消息
  showInfo(message: string) {
    ElMessage.info(message)
  }
}

// 创建全局错误处理器实例
export const errorHandler = new ErrorHandler()

// 便捷的错误处理函数
export const handleError = {
  api: (error: AxiosError, source?: string) => errorHandler.handleApiError(error, source),
  business: (message: string, details?: ErrorDetail[], source?: string) => 
    errorHandler.handleBusinessError(message, details, source),
  validation: (message: string, details?: ErrorDetail[], source?: string) => 
    errorHandler.handleValidationError(message, details, source),
  show: (error: AppError | Error | string, showDetails = false) => 
    errorHandler.showError(error, showDetails),
  success: (message: string) => errorHandler.showSuccess(message),
  warning: (message: string) => errorHandler.showWarning(message),
  info: (message: string) => errorHandler.showInfo(message)
}

export default errorHandler 